package com.mindether.llyblog.controller;

import com.mindether.llyblog.pojo.*;
import com.mindether.llyblog.service.ArticleSearchService;
import com.mindether.llyblog.service.ArticleService;
import com.mindether.llyblog.service.CommentService;
import com.mindether.llyblog.service.TagService;
import com.mindether.llyblog.utils.IdWorker;
import com.mindether.llyblog.utils.Utils;
import javafx.beans.binding.ObjectExpression;
import org.apache.commons.lang.StringUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.annotation.PostConstruct;
import javax.servlet.ServletRequest;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Logger;

@RequestMapping(value = "/article")
@Controller
@CrossOrigin
public class ArticleController {
    public static List<Tag> allTags=new ArrayList<>();
    //缓存标签
    @PostConstruct
    public void initTags(){
        allTags.addAll(tagService.findAllTags());
    }
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private ArticleService articleService;
    @Autowired
    private TagService tagService;
    @Autowired
    private CommentService commentService;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ArticleSearchService articleSearchService;
    //每页的记录数
    @Value("${lly.blog.pagesize}")
    private int pageSize;

    org.slf4j.Logger log= LoggerFactory.getLogger(ArticleController.class);

    /**
     * 增加一篇文章
     * @param article
     * @return
     */
    @RequestMapping(method = RequestMethod.POST)
    @ResponseBody
    public ApiResponse addArticle(@RequestBody Article article){
        article.setUpdatetime(Utils.getNow());
        article.setId(idWorker.nextId()+"");
        article.setCreatetime(Utils.getNow());
        article.setComment(0);
        article.setThumbup(0);
        article.setVisits(0);

        articleService.addArticle(article);
        ArticleSearch articleSearch=new ArticleSearch();
        BeanUtils.copyProperties(article,articleSearch);
        articleSearchService.addArticleIndex(articleSearch);
        return ApiResponse.ok().setMessage("新增成功");
    }

    /**
     * 根据关键字搜索文章
     * @param model
     * @param keywords
     * @param page
     * @param size
     * @return
     */
    @RequestMapping(value="/search/{keywords}/{page}",method = RequestMethod.GET)
    public String searchArticle(Model model,@PathVariable("keywords")String keywords,@PathVariable("page")Integer page){

        model.addAttribute("allTags",allTags);
        keywords= StringUtils.trim(keywords);
        ApiPageResponse<ArticleSearch> articleApiPageResponse=new ApiPageResponse<>();
        Page<ArticleSearch> pageArticle=articleSearchService.findByTitleOrContentLike(keywords,page,this.pageSize);
        articleApiPageResponse.setTotal(pageArticle.getTotalPages());
        articleApiPageResponse.setSize(pageArticle.getTotalElements());
        articleApiPageResponse.setPageSize(this.pageSize);

        for(ArticleSearch articleSearch:pageArticle.getContent()){
            String beforeKeywords=articleSearch.getContent();
            int start=beforeKeywords.indexOf(keywords);

            if(start>-1){
                String fixedKeywords=beforeKeywords.substring(start-20<0?0:start-20,start+20>beforeKeywords.length()?beforeKeywords.length():start+20);
                fixedKeywords=fixedKeywords.replace(keywords,"<span  style=\"font-size:30px;color:red;\">"+keywords+"</span>");
                articleSearch.setIntro(fixedKeywords);
            }
            beforeKeywords=articleSearch.getTitle();
            start=beforeKeywords.indexOf(keywords);
            if(start>-1){
                String fixedKeywords=beforeKeywords.substring(start-20<0?0:start-20,start+20>beforeKeywords.length()?beforeKeywords.length():start+20);
                fixedKeywords=fixedKeywords.replace(keywords,"<span  style=\"font-size:30px;color:red;\">"+keywords+"</span>");
                articleSearch.setTitle(fixedKeywords);
            }
        }
        articleApiPageResponse.setRows(pageArticle.getContent());
        model.addAttribute("articleTagPage",articleApiPageResponse);

        return "list";
    }
    /**
     * 更新文章
     * @param id
     * @param article
     * @return
     */
    @RequestMapping(value="/{id}",method = RequestMethod.PUT)
    @ResponseBody
    public Object updateArticle(@PathVariable("id")String id,@RequestBody Article article){
        article.setId(id);
        article.setUpdatetime(Utils.getNow());
        articleService.updateArticle(article);
        ArticleSearch articleSearch=new ArticleSearch();

        BeanUtils.copyProperties(article,articleSearch);
        articleSearchService.updateArticle(articleSearch);
        return ApiResponse.ok().setMessage("更新成功");
    }

    /**
     * 根据ID删除文章
     * @param id
     * @return
     */
    @RequestMapping(value="/{id}",method = RequestMethod.DELETE)
    @ResponseBody
    public Object deleteArticle(@PathVariable String id){
        articleService.deleteById(id);
        articleSearchService.deleteById(id);
        return ApiResponse.ok().setMessage("删除成功");
    }

    @RequestMapping(value="/disable/{id}",method = RequestMethod.PUT)
    @ResponseBody
    public Object disableArticle(@PathVariable String id){
        return null;
    }

    /**
     * 根据ID查询某篇文章
     * @param id
     * @param model
     * @param request
     * @return
     */
    private Lock lock=new ReentrantLock();
    @RequestMapping(value="/{id}",method = RequestMethod.GET)
    public String findArticleById(@PathVariable("id")String id, Model model, ServletRequest request){
        int i=10/0;
        String host=request.getRemoteAddr();
        String key=(host+id).hashCode()+"";
        Object value=redisTemplate.opsForValue().get(key);
        if(value==null){
            synchronized (ArticleController.class){
                if(value==null) {
                    redisTemplate.opsForValue().set(key, key, 6, TimeUnit.HOURS);
                    articleService.increaseArticleVisit(id);
                }
            }
        }
        //假静态页面去掉.html
        id=id.replaceAll(".html","");

        //Article article=articleService.getArticleById(id);
        Article article=(Article) redisTemplate.boundValueOps(id+"").get();
        if(article==null){
            try {
                lock.lock();
                if(article==null){
                    article=articleService.getArticleById(id);
                    redisTemplate.boundValueOps(id).set(article,24,TimeUnit.HOURS);
                }
            }catch (Exception ex){
                ex.printStackTrace();
            }finally {
                lock.unlock();
            }
        }
        //获取相关的文章
        List<Article>  relateArticleList=articleService.findRelateArticle(article.getTag());
        relateArticleList.remove(article);
        //获取评论
        List<Comment> comments=commentService.findCommentListByArticleId(article.getId());

        model.addAttribute("allTags",allTags);
        model.addAttribute("article",article);
        model.addAttribute("relateArticleList",relateArticleList);
        model.addAttribute("comments",comments);

        return "show";
    }

    /**
     * 查询某一篇文章，供后台管理使用
     * @param id
     * @param model
     * @param request
     * @return
     */
    @RequestMapping(value="/font/{id}",method = RequestMethod.GET)
    @ResponseBody
    public ApiResponse findArticleByIdForFont(@PathVariable("id")String id, Model model, ServletRequest request){
        Article article=articleService.getArticleById(id);
        return ApiResponse.ok().setMessage("查询成功").setData(article);
    }

    /**
     * 根据标签查询文章，实际返回该标签下第一页文章
     * @param tag
     * @param model
     * @return
     */
    @RequestMapping(value="/tag/{tagname}",method = RequestMethod.GET)
    public String findArticleListByTag(@PathVariable("tagname")String tag, Model model){

        model.addAttribute("allTags",allTags);
        ApiPageResponse<Article> articleTagPage= articleService.findArticleByTagAndPage(1,this.pageSize,tag);
        model.addAttribute("articleTagPage",articleTagPage);

        return "list";
    }

    /**
     *      根据标签分页查询文章
     * @param tag
     * @param page
     * @param model
     * @return
     */
    @RequestMapping(value="/tag/{tagname}/page/{page}",method = RequestMethod.GET)
    public String pageArticleListByTag(@PathVariable("tagname")String tag, @PathVariable("page")Integer page, Model model){

        ApiPageResponse<Article> articleTagPage= articleService.findArticleByTagAndPage(page,pageSize,tag);
        model.addAttribute("allTags",allTags);
        model.addAttribute("articleTagPage",articleTagPage);

        return "list";
    }

}
